package com.atguigu.gmall.realtime.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.realtime.common.GmallConfig;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hbase.client.Connection;
import redis.clients.jedis.Jedis;

/**
 * @author Felix
 * @date 2023/11/20
 * 查询维度的工具类
 */
public class DimUtil {
    /**
     * 根据维度的主键获取维度数据 旁路缓存
     *
     * @param jedis     redis客户端连接
     * @param conn      hbase连接
     * @param namespace hbase的"库"
     * @param tableName 维度表名
     * @param rowkey    维度主键
     * @return
     * 旁路缓存
     *      思路：先从缓存中获取维度数据，如果缓存中找到了要关联的维度，直接将其作为方法的返回值进行返回(缓存命中)；
     *           如果从缓存中没有找到要关联的维度，那么发送请求到hbase表中将维度数据查询出来，并将查询出的维度数据
     *           放到缓存中，方便下次查询使用
     * 缓存产品选型：
     *      本地状态： 性能很好，维护性差
     *      Redis：   性能不错，维护性好  √
     * 关于Redis的一些配置
     *      key:    维度表表名:主键值
     *      type:   String
     *      expire: 1day
     * 注意：当维度数据发生变化之后，将Redis中缓存的数据清除掉
     */
    public static JSONObject getDimInfo(Jedis jedis, Connection conn, String namespace, String tableName, String rowkey) {
        //拼接从Redis中查询维度数据的key
        String redisKey = tableName.toLowerCase() + ":" + rowkey;

        String dimInfoStr = null;
        JSONObject dimJsonObj = null;
        //先从缓存中获取维度数据
        dimInfoStr = jedis.get(redisKey);
        if (StringUtils.isNotEmpty(dimInfoStr)) {
            //如果缓存中找到了要关联的维度，直接将其作为方法的返回值进行返回(缓存命中)
            System.out.println("~~从Redis中查询" + tableName + "表的" + rowkey + "维度数据~~");
            dimJsonObj = JSON.parseObject(dimInfoStr);
        } else {
            // 如果从缓存中没有找到要关联的维度，那么发送请求到hbase表中将维度数据查询出来
            System.out.println("~~从Hbase中查询" + tableName + "表的" + rowkey + "维度数据~~");
            dimJsonObj = HbaseUtil.getDimInfoFromHbase(conn, namespace, tableName, rowkey);
            if (dimJsonObj != null) {
                //将查询出的维度数据放到缓存中，方便下次查询使用
                jedis.setex(redisKey, 3600 * 24, dimJsonObj.toJSONString());
            } else {
                System.out.println("~~要查询的" + tableName + "表的" + rowkey + "维度数据不存在~~");
            }
        }

        return dimJsonObj;
    }

    //清除Redis中缓存数据
    public static void deleteCached(String tableName,String rowkey){
        String redisKey = tableName.toLowerCase() + ":" + rowkey;
        Jedis jedis = null;
        try {
            jedis =  RedisUtil.getRedisConnection();
            jedis.del(redisKey);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(jedis != null){
                RedisUtil.closeRedisConnection(jedis);
            }
        }
    }
    public static void main(String[] args) {
        Jedis jedis = RedisUtil.getRedisConnection();
        Connection hbaseConn = HbaseUtil.getHbaseConnection();
        System.out.println(getDimInfo(jedis, hbaseConn, GmallConfig.HBASE_NAMESPACE, "dim_base_trademark", "1"));
    }
}
